package util.filters;


import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

/**
 * Zadaje se maksimalan broj cifara
 * JTextField cijiem se dokumentu postavi ovaj filter moci ce da primi samo cifre
 * Koristi se kada je maksimalan sadrzaj od jedne do maxLength cifara, recimo za redni broj
 * @author Renata
 *
 */
public class MaxDigitsDecimalDocumentFilter extends DocumentFilter{
	/**
	 * Maksimalni broj cifara
	 */
	private int maxLength = 0;
	private int maxDecimalPlaces = 0;
	private char decimalCharacter = ',';
	
	public MaxDigitsDecimalDocumentFilter(char decimalCharacter){
		super();
		this.decimalCharacter = decimalCharacter;
	}

	/**
	 * Poziva se kada se nesto ukuca ili paste-uje
	 */
	public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
	throws BadLocationException
	{
		String newString;
		if(fb.getDocument().getLength() > 0){
			String original = fb.getDocument().getText(0, fb.getDocument().getLength());
			if(offset == original.length()){
				newString = original + string;
			}else{
				newString = original.substring(0, offset) + string + original.substring(offset + 1, original.length());
			}
		}else{
			newString = string;
		}

		//Sve ok, pozovi insert
		if(isValid(newString)){
			fb.insertString(offset, string, attr);
		}
	}

	/**
	 * Poziva se kada se nesto replace-uje, bilo da se kuca ili paste-uje
	 */
	public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
	throws BadLocationException
	{
		String newString;
		if(fb.getDocument().getLength() > 0){
			String original = fb.getDocument().getText(0, fb.getDocument().getLength());
			if(length == 0){
				if(offset == original.length()){
					newString = original + text;
				}else{
					newString = original.substring(0, offset) + text + original.substring(offset, original.length());
				}
			}else{
				if(offset == original.length()){
					newString = original + text;
				}else{
					newString = original.substring(0, offset) + text + original.substring(offset + length, original.length());
				}
			}
		}else{
			newString = text;
		}
		
		if(isValid(newString)){
			fb.replace(offset, length, text, attrs);
		}
	}

	/**
	 * Proverava da li su sve cifre
	 * @param text za koji se proverava
	 * @return
	 */
	private boolean allDigits(String text) {
		for (int pos=0; pos < text.length(); pos++) {
			if (!Character.isDigit(text.charAt(pos)) && text.charAt(pos) != decimalCharacter) {
				return false;
			}
		}
		return true;
	}
	
	private boolean isValid(String text){
		if(text == null){
			return false;
		}
		if(text.length() == 0){
			return true;
		}
		int numberOfDecimalPoints = 0;
		int numberOfDigits = 0;
		int numberOfDecimals = 0;
		int numberOfDigitsBeforeDecimalPoint = 0;
		
		for(int i = 0; i < text.length(); i++){
			char c = text.charAt(i);
			
			if(!Character.isDigit(c) && c != decimalCharacter){
				return false;
			}
			
			if(Character.isDigit(c)){
				numberOfDigits++;
				if(numberOfDecimalPoints == 1){
					numberOfDecimals++;
				}else{
					numberOfDigitsBeforeDecimalPoint++;
				}
			}
			
			if(c == decimalCharacter){
				numberOfDecimalPoints++;
			}
		}
		
		if(numberOfDigits > maxLength){
			return false;
		}
		if(numberOfDecimals > maxDecimalPlaces){
			return false;
		}
		if(numberOfDigitsBeforeDecimalPoint == 0){
			return false;
		}
		if(numberOfDecimalPoints > 1){
			return false;
		}
		if(numberOfDigitsBeforeDecimalPoint == maxLength && numberOfDecimalPoints > 0){
			return false;
		}
		
		return true;
	}

	public int getMaxLength() {
		return maxLength;
	}

	public void setMaxLength(int maxLength) {
		this.maxLength = maxLength;
	}

	public int getMaxDecimalPlaces() {
		return maxDecimalPlaces;
	}

	public void setMaxDecimalPlaces(int maxDecimalPlaces) {
		this.maxDecimalPlaces = maxDecimalPlaces;
	}
	
	
}
